/*
* INSANE - Interactive Structural Analysis Environment
*
* Copyright (C) 2003-2005
* Universidade Federal de Minas Gerais
* Escola de Engenharia
* Departamento de Engenharia de Estruturas
* 
* Author's email :    insane@dees.ufmg.br
* Author's website :  http://www.dees.ufmg.br/insane
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
* 
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package br.ufmg.dees.insane.ui.rich.full.command;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

import javax.swing.JInternalFrame;

import br.ufmg.dees.insane.commons.command.Command;
import br.ufmg.dees.insane.commons.controller.Controller;
import br.ufmg.dees.insane.model.geo.GCubicCurve;
import br.ufmg.dees.insane.model.geo.GCurve;
import br.ufmg.dees.insane.model.geo.GLine;
import br.ufmg.dees.insane.model.geo.GPoint;
import br.ufmg.dees.insane.model.geo.GQuadCurve;
import br.ufmg.dees.insane.model.geo.GRegion;
import br.ufmg.dees.insane.ui.rich.full.InsaneInternalInterface;
import br.ufmg.dees.insane.ui.rich.full.controller.RegionController;

/**
 *
 * @author Pitangueira, Roque & Brugiolo, Marco & Fonseca, Flavio
 * @version 0.0.1 Beta
 */
public class AddRegionCommand implements Command, Cloneable {
    
    private InsaneInternalInterface parent;
    private Controller controller;
    private GRegion rg;
	
	String message;
    
//*****************************************************************************
	
    /** Creates new AddRegionCommand */
    public AddRegionCommand(JInternalFrame parent) {
		this.parent = (InsaneInternalInterface)parent;
		controller = this.parent.getController();
	}
	
//*****************************************************************************
	
    public void execute() {
		boolean isRegion = false;
		ArrayList cvs = ((RegionController)controller).getNewCurves();
		ArrayList curves  = (ArrayList) cvs.clone();
		int label = ((RegionController)controller).getLabelRegion();
		
		if ( curves.size() == 2 ) {
			isRegion = isLofting(curves);
		}
		if ( curves.size() == 3 ) {
			isRegion = isTrilinear(curves);
		}
		if ( curves.size() == 4 ) {
			isRegion = isBilinear(curves);
		}
		if ( isRegion ) {
			rg = new GRegion(label, curves);
			
			message = parent.getResourceBundle().getString("cmRegion01") + ", R" + rg.getLabel() + ":";
			
			ListIterator gcvs = curves.listIterator();
			while(gcvs.hasNext()) {
				GCurve cv = (GCurve)gcvs.next();
				message = message + " C" + cv.getLabel() + ",";
				Object obj;
				List primitives = cv.getPrimitives();
		        ListIterator prs = primitives.listIterator();
				while(prs.hasNext()) {
					obj = prs.next();
					if (obj instanceof GPoint) {
						GPoint prmt = (GPoint)obj;
						prmt.setColor( ((RegionController)controller).getBoundaryColor() );
					}
					if (obj instanceof GLine) {
						GLine prmt = (GLine)obj;
						prmt.setColor( ((RegionController)controller).getBoundaryColor() );
					}
					if (obj instanceof GQuadCurve) {
						GQuadCurve prmt = (GQuadCurve)obj;
						prmt.setColor( ((RegionController)controller).getBoundaryColor() );
					}
					if (obj instanceof GCubicCurve) {
						GCubicCurve prmt = (GCubicCurve)obj;
						prmt.setColor( ((RegionController)controller).getBoundaryColor() );
					}
				}
			}
			
			parent.getController().add(rg);
			parent.getDrawing().repaint();
		}
		
		parent.addOutputText(message);
	}
	
//*****************************************************************************
	
	public boolean isLofting(List curves) {
		int nPoint = 0;
		message = parent.getResourceBundle().getString("cmRegion02");
		for (int i = 0; i < 2; i++) {
			GCurve gc = (GCurve)curves.get(i);
			Point2D p1 = gc.getFirstPoint();
			Point2D p2 = gc.getEndPoint();
			if (curves.size()==1) {
				if (isEqual(p1, p2) ) {
					nPoint = nPoint + 1;
					if (nPoint > 1) {
						message = message + (i+1) +" " + parent.getResourceBundle().getString("cmRegion03")+")";
						return false;
					}
					message = message + (i+1) +" " + parent.getResourceBundle().getString("cmRegion04") + " ";
				}
			}
		}
		return true;
	}
	
//*****************************************************************************
	
	public boolean isTrilinear(List curves) {
		for (int i = 0; i < 3; i++) {
			boolean isContinuos1 = false;
			boolean isContinuos2 = false;
			GCurve gc = (GCurve)curves.get(i);
			Point2D p1 = gc.getFirstPoint();
			Point2D p2 = gc.getEndPoint();
			if (isEqual(p1, p2) ) {
				message = parent.getResourceBundle().getString("cmRegion02") +(i+1)+ " " + parent.getResourceBundle().getString("cmRegion05")+")";
				return false;
			}
			for (int j = 0; j < 3; j++) {
				if ( i != j ) {
					GCurve gcv = (GCurve)curves.get(j);
					Point2D pt1 = gcv.getFirstPoint();
					Point2D pt2 = gcv.getEndPoint();
					if (isEqual(p1,pt1) || isEqual(p1,pt2) ){
						isContinuos1 = true;
					} 
					if (isEqual(p2,pt1) || isEqual(p2,pt2) ){
						isContinuos2 = true;
					} 
				}
			}
			if ( (isContinuos1 == false) || (isContinuos2 == false) ) {
				message = parent.getResourceBundle().getString("cmRegion02") +(i+1)+" " + parent.getResourceBundle().getString("cmRegion06")+")";
				return false;
			}
		}
		return true;
	}
	
//*****************************************************************************
	
	public boolean isBilinear(List curves) {
		int nPoint = 0;
		message = parent.getResourceBundle().getString("cmRegion02");
		for (int i = 0; i < 4; i++) {
			boolean isContinuos1 = false;
			boolean isContinuos2 = false;
			GCurve gc = (GCurve)curves.get(i);
			Point2D p1 = gc.getFirstPoint();
			Point2D p2 = gc.getEndPoint();
			if (curves.size()==1) {
				if (isEqual(p1, p2) ) {
					nPoint = nPoint + 1;
					if (nPoint > 1) {
						message = message + (i+1) +" " + parent.getResourceBundle().getString("cmRegion03") +")";
						return false;
					}
					message = message + (i+1) + " " + parent.getResourceBundle().getString("cmRegion04")+ " ";
				}
			}
			for (int j = 0; j < 4; j++) {
				if ( i != j ) {
					GCurve gcv = (GCurve)curves.get(j);
					Point2D pt1 = gcv.getFirstPoint();
					Point2D pt2 = gcv.getEndPoint();
					if (isEqual(p1,pt1) || isEqual(p1,pt2) ){
						isContinuos1 = true;
					} 
					if (isEqual(p2,pt1) || isEqual(p2,pt2) ){
						isContinuos2 = true;
					} 
				}
			}
			if ( (isContinuos1 == false) || (isContinuos2 == false) ) {
				message = parent.getResourceBundle().getString("cmRegion02") +(i+1)+" " + parent.getResourceBundle().getString("cmRegion06")+")";
				return false;
			}
		}
		return true;
	}
	
//*****************************************************************************
	
	public boolean isEqual(Point2D p1, Point2D p2) {
		if (p1.getX() != p2.getX() ) {
			return false;
		} else {
			if (p1.getY() != p2.getY() ) {
				return false;
			}else{
				return true;
			}
		}
	}
	
//*****************************************************************************
	
	/** Impossible to undo - Not implemented */
    public void undo() {}
    
//*****************************************************************************
	
	/** Impossible to redo - Not implemented */
    public void redo() {}
	
//*****************************************************************************
}

